<script setup lang="ts">
import {
  computed,
  nextTick,
  onMounted,
  onBeforeMount,
  onBeforeUnmount,
  provide,
  reactive,
  ref,
  toRaw,
  watch,
} from "vue";
import { Message } from "@arco-design/web-vue";
import bus from "./tools/bus";
import { GroupType } from "./tools/emun";
import Video from "./components/Video.vue";
import VideoList from "./components/VideoList.vue";
import { useFilmReadRight } from "../../store";
import type * as VideoType from "./type";
import type { NidusItem, VideoItem } from "./type";
import * as DataTransfer from "./tools/dataTransfer";
import * as VideoApi from "./http/videoLabel";
import { useRoute } from "vue-router";
import JsZip from "jszip";
import JSZipUtils from "jszip-utils";
import { getComponentData } from "@/store/modules/filmReadHeader/util";
import { usePageType } from "./tools/usePageType";
import useVideo from "@/store/modules/video";
import * as Store from "@/store";
import Bus from "@/utils/bus";
import useUtils from "@/views/filmRead/hooks/useUtils";
import useLeft from "@/views/filmRead/hooks/useLeft";

const { isView, isCreate, isEdit } = usePageType();
const videoStore = useVideo();
const filmReadStore = Store.useFilmRead();
const filmReadRight = useFilmReadRight();
const utilHooks = useUtils();
const leftHooks = useLeft();
const route = useRoute();
const isInputBlur = ref(true);
const loading = ref(true);
const title = ref("");
const nidusList = ref<VideoType.NidusItem[]>([]); //当前检查下的所有序列

const taskId = ref<string>("");
const userId = ref<string>("");

const currentVideoIndex: any = ref(0); //当前层数

// const taskInfo: any = ref({});
const projectInfo: any = ref({});
const dictList: any = ref([]);
// const lesionSetting: any = ref([]);
// const commonConfig: any = ref([]);
const toolData: any = ref([]);
const currentToolData: any = ref({}); //当前工具的数据
//序列组下的序列数据
const videoList = ref<VideoItem[]>([]);

// 获取废片弹窗内容详情
const scrapList = ref(<{ name: string; value: string }[]>[]);

// 处理废片集合
const processData = (list: any) => {
  //添加默认
  if (!list.some((item: any) => item.value == "98")) {
    list.push({ value: "98", name: "序列加载异常" });
  }
  if (!list.some((item: any) => item.value == "99")) {
    list.push({ value: "99", name: "其他" });
  }
  scrapList.value = list.map((item: { value: any; name: any }) => {
    return {
      value: item.value,
      name: item.name,
    };
  });
};

// 序列集合
const seriesInfo = ref<any>({});

const Keyboard = {
  ArrowLeft: "ArrowLeft",
  ArrowRight: "ArrowRight",
  blank: " ", // 空格键
};

const keyboardUp = () => {
  isFlag.value = false;
  bus.emit("VideoLabel.keyup");
};

//按键抬起
const keyup = (e: any) => {
  const { key } = e || {};
  const config = {
    [Keyboard.ArrowLeft]: keyboardUp, // 左键松开
    [Keyboard.ArrowRight]: keyboardUp, // 右键松开
  };
  if (config.hasOwnProperty(key)) {
    config[key]();
  }
};

// 按键按下
const keydown = (e: any) => {
  if (e.target.localName === "body") {
    e.preventDefault();
  }
  if (isInputBlur.value) {
    const { key, repeat } = e || {};
    const config = {
      [Keyboard.ArrowLeft]: keyboardLeftDown,
      [Keyboard.ArrowRight]: keyboardRightDown,
      [Keyboard.blank]: keyboardBlankDown,
    };
    if (config.hasOwnProperty(key)) {
      config[key](repeat);
    }
  }
};

// 是否是长按
// 键盘左键
const keyboardLeftDown = (repeat: boolean) => {
  if (repeat) {
    //长按
    if (isFlag.value) return;
    isFlag.value = true;
    bus.emit("VideoLabel.leftLongPress");
  } else {
    bus.emit("VideoLabel.leftClickPress");
  }
};

const isFlag = ref(false);
//键盘右键
const keyboardRightDown = (repeat: boolean) => {
  if (repeat) {
    //长按
    if (isFlag.value) return;
    isFlag.value = true;
    bus.emit("VideoLabel.rightLongPress");
  } else {
    bus.emit("VideoLabel.rightClickPress");
  }
};

const keyboardBlankDown = () => {
  if (isInputBlur.value) {
    bus.emit("VideoLabel.keyboardBlankDown");
  }
};

const submitUserId = ref<string>("");
const serialNumber = ref<string>(""); //序列号
const isStart = ref<string>(""); //从开始任务的入口进入
// 初始序列集合
const seriesGroupList = ref<any>([]);
const groupIndex = ref(0); //任务下检查序号
//病灶列表
const nidusListRef = ref<any>(null);
onBeforeMount(async () => {
  offBusEvent();
  //左边列表事件
  Bus.on("lesionClick", nidusListClick);
  //顶部工具事件
  Bus.on("toolBarClick", toolbarClick);
});
const nidusListClick = (data: any) => {
  console.log("病灶列表点击", data);
  const { type, id, currentItem, isLesion, activeKey, isShowAll } = data;
  const { visibile, tool, result } = currentItem || {};
  switch (type) {
    case "frame": //点击帧段
      const [frameItem, seriesIdx, frameIdx] = findFrameById(id);
      setFrameActive(seriesIdx, frameIdx, visibile);
      //收起帧段，反选下面所有病灶
      !visibile &&
        frameItem.child.map((item, thirdIndex) => {
          if (item.isActive) {
            setNidusActive(seriesIdx, frameIdx, thirdIndex, false);
            setNidusListColor(seriesIdx, frameIdx, thirdIndex, false);
          }
        });
      break;
    case "lesion": //点击病灶
      const selected = !(isLesion === "");
      const { getLabelIndex } = DataTransfer.getToolInfo(tool);
      const labelIndex = getLabelIndex(result.data);
      changeVideoIndex({ labelIndex, data: {} });
      if (data.groupId === 0) {
        //单帧病灶
        videoStore.setSingleSelected(currentSeriesUid.value, id);
        const thirdItem = videoStore.getSingleListItemById(id);
        setSingleColor(thirdItem, selected);
      } else {
        //帧段下病灶
        const [nidusItem, index, subIndex, thirdIndex] = findNidusById(id);
        setNidusActive(index, subIndex, thirdIndex, selected);
        // setFrameActive(0, 0, true);如果单帧是否反选帧段
        setNidusListColor(index, subIndex, thirdIndex, selected);
      }
      break;
    case "frameEyes": //帧段隐藏/显示
      const res = findFrameById(id);
      nidusToggleShowOrHide([res[1], res[2], null]);
      break;
    case "eyes": //病灶隐藏/显示
      if (data.groupId === 0) {
        //单帧
        const thirdItem = videoStore.getSingleListItemById(id);
        thirdItem && singleEyeClick(thirdItem);
      } else {
        const nidusRes = findNidusById(id);
        nidusToggleShowOrHide([nidusRes[1], nidusRes[2], nidusRes[3]]);
      }
      break;
    case "del": //删除病灶
      if (data.groupId === 0) {
        //单帧
        const thirdItem = videoStore.getSingleListItemById(id);
        delSingle(thirdItem);
        utilHooks.lesionEvent.lesionDel(id); //通知周边组件删除对应数据
      } else {
        //帧段下的
        const nidusArr = findNidusById(id);
        removeNidus([nidusArr[1], nidusArr[2], nidusArr[3]]);
        utilHooks.lesionEvent.lesionDel(id, data.groupId); //通知周边组件删除对应数据
      }

      break;
    case "delFrame": //删除帧段
      const frameArr = findFrameById(id);
      removeNidus([frameArr[1], frameArr[2], null]);
      utilHooks.lesionEvent.frameDel(id); //通知周边组件删除对应数据
      break;
    // lesionDel(item.id);
    // lesionSetActive(item.id.toString());
    // UtilsHooks.lesionEvent.lesionSetActive(item.id.toString());
    // frameDel(item.id)
    case "all": //标签选中
      if (activeKey === "multi") {
        //帧段tab选中
        videoStore.activeAnnoTab = activeKey;
      } else if (activeKey === "single") {
        //单帧tab选中
        videoStore.activeAnnoTab = activeKey;
      } else if (isShowAll === true) {
        //全部显示
        hideAll(isShowAll);
      } else if (isShowAll === false) {
        //全部隐藏
        hideAll(isShowAll);
      }
      break;
  }
};
//根据id获取frameItem(index、subIndex)?
const findFrameById = (frameId: any) => {
  let seriesIdx: any = null,
    frameIdx: any = null;
  let frameItem = null;
  for (seriesIdx = 0; seriesIdx < nidusList.value.length; seriesIdx++) {
    const seriesItem = nidusList.value[seriesIdx];
    for (frameIdx = 0; frameIdx < seriesItem.child.length; frameIdx++) {
      const frameItem = seriesItem.child[frameIdx];
      if (frameItem.id === frameId) {
        return [frameItem, seriesIdx, frameIdx];
      }
    }
  }
  return [frameItem, seriesIdx, frameIdx];
};
//根据id获取nidusItem(index、subIndex、thirdIndex)?
const findNidusById = (nidusId: any) => {
  let seriesIdx: any = null,
    frameIdx: any = null,
    nidusIdx: any = null;
  let nidusItem: any = null;
  for (seriesIdx = 0; seriesIdx < nidusList.value.length; seriesIdx++) {
    const seriesItem = nidusList.value[seriesIdx];
    for (frameIdx = 0; frameIdx < seriesItem.child.length; frameIdx++) {
      const frameItem = seriesItem.child[frameIdx];
      for (nidusIdx = 0; nidusIdx < frameItem.child.length; nidusIdx++) {
        nidusItem = frameItem.child[nidusIdx];
        if (nidusItem.id === nidusId) {
          return [nidusItem, seriesIdx, frameIdx, nidusIdx];
        }
      }
    }
  }
  return [nidusItem, seriesIdx, frameIdx, nidusIdx];
};
//删除单帧
const delSingle = async (thirdItem: any) => {
  videoStore.delSingle(thirdItem.id);
  /*await VideoApi.deleteAnnoResult({
    id: thirdItem.id
  })*/
  bus.emit("VideoLabel.removeNidus", {
    thirdItem,
  });
  if (thirdItem.isActive) {
    // setBigSign(); todo
  }
};
const toolbarClick = (data: any) => {
  console.log("工具栏", data);
  const { isTool, currentItem, lesion } = data;
  const { code, isActive, toolType, type } = currentItem || {};
  const { color } = lesion || {};
  switch (code) {
    case "windowAdjustment": //wl
      const { ctWlww } = data;
      if (isTool === undefined && ctWlww) {
        //wl下拉选中
        const wlArr = ctWlww.split("*");
        bus.emit("VideoLabel.setWL", { wl: wlArr[0], ww: wlArr[1] });
      } else if (!isTool && !ctWlww && isActive) {
        //选中wl
        videoStore.currnetToolName = "Wwwc";
        bus.emit("VideoLabel.wwwcToolsChange", { toolName: "Wwwc", isSeleted: isActive });
      } else if (!isTool && !ctWlww && !isActive) {
        //取消wl
        videoStore.currnetToolName = "";
        bus.emit("VideoLabel.wwwcToolsChange", { toolName: "Wwwc", isSeleted: isActive });
      }
      break;
    case "zoom": //缩放
      let toolData: any = {
        toolName: "Zoom",
        active: isActive,
      };
      videoStore.currnetToolName = "Zoom";
      bus.emit("VideoLabel.labelToolsChange", toolData);
      break;
    case "RECTANGLE": //矩形
    case "FREEHANDLINECLOSED": //自由画笔
      const {
        name,
        toolName,
        getLabelIndex,
        modeltoctrenderdata,
      } = DataTransfer.getToolInfo(toolType);
      let toolsData: any = {
        toolName: toolName,
        arId: currentNidus.value.sarId,
        lesion: lesion.lesion,
        tool: toolType,
        color: color,
      };
      if (isTool) {
        //tool active
        //todo
        toolsData.active = true;
        if (videoStore.isMulti) {
          toolsData.groupId = videoStore.activeFrame.id;
        }
        videoStore.currnetToolName = toolName;
        currentToolData.value = toolsData;
        bus.emit("VideoLabel.labelToolsChange", toolsData);
      } else if (!isTool && isActive) {
        //开启tool
      } else if (!isTool && !isActive) {
        //禁用tool创建
        toolsData.active = false;
        videoStore.currnetToolName = "";
        bus.emit("VideoLabel.labelToolsChange", toolsData);
      }
      break;
    case "trace": //追踪
      currentItem.isActive = false; //取消高亮
      currentItem.isVisible = false; //取消弹出面板
      handleTrace();
      break;
  }
};
onMounted(async () => {
  removeEvent();
  document.addEventListener("keydown", keydown);
  document.addEventListener("keyup", keyup);

  const accessToken = route.query.token;
  if (accessToken) {
    localStorage.setItem("accessToken", (accessToken || "").toString());
  }
  const userIdRef = route.query.userId;
  userId.value = (userIdRef || "") as string;
  const taskIdRef = route.query.id;
  taskId.value = (taskIdRef || "") as string;

  const _serialNumber = route.query.serialNumber;
  serialNumber.value = (_serialNumber || "") as string;
  const _submitUserId = route.query.submitUserId;
  submitUserId.value = (_submitUserId || "") as string;
  //事件注册
  bus.on("Video.setLoading", setLoading);
  title.value = "标注-超声视频标注";
  bus.on("Cornerstone.measurementModified", measurementModified);
  bus.on("Cornerstone.measurementAdded", measurementAdded);
  bus.on("Cornerstone.measurementCompleted", completed);
  bus.on("Cornerstone.remove", remove);
  bus.on("Video.handleClickTimer", handleClickTimer);
  bus.on("Video.changeVideoIndex", (videoIndex) => {
    currentVideoIndex.value = videoIndex;
  });
  bus.on("NidusList.removeNidus", removeNidus);
  bus.on("NidusList.nidusToggleShowOrHide", (indexs: any) =>
    nidusToggleShowOrHide(indexs)
  );
  bus.on("Video.slideChange", (dataArray: any) => slideChange(dataArray));
  bus.on("sign.inputEvent", (isBlur: any) => {
    isInputBlur.value = isBlur;
  });
  bus.on("Video.NidusIndexChange", nidusIndexChange);
  bus.on("Tools.change", toolsChange);
  bus.on("sign.bigChang", bigChang);
  bus.on("sign.smallChang", smallChang);
  bus.on("NidusList.selectedBigSign", (index: any) => selectedBigSign(index));
  bus.on("NidusList.changeIsOpen", (indexs: any) => {
    const [index, subIndex] = indexs;
    const isOpen = !nidusList.value[index].child[subIndex].isOpen;
    nidusList.value[index].child[subIndex].isOpen = isOpen;
  });
  bus.on("NidusList.refresh", async () => {
    await setNidusList();
    //重新计算帧段的单位显示大小
    nidusList.value.forEach((item: NidusItem, index: number) => {
      const cellWidth = cellWidthObj.value[item.id];
      slideChange([cellWidth, item.id]);
    });
    //add tool state,clear first
    // console.log("before clear",cornerstoneTools.globalImageIdSpecificToolStateManager.toolState)
    // cornerstoneTools.globalImageIdSpecificToolStateManager.toolState = {}
    bus.emit("Video.addtoolstate");
  });
  bus.on("NidusList.changeSubItemActive", (indexs: any) => {
    const [index, subIndex, isActive] = indexs;
    setNidusActive(index, 0, 0, false);
    setFrameActive(index, subIndex, isActive);
    setNidusListColor(index, 0, 0, false);
    setToolDisabled();
    setBigSign();
  });
  bus.on("NidusList.toggleNidusItemHide", (indexs: any) => {
    const [index] = indexs;
    console.log(indexs, "NidusList.toggleNidusItemHide");
    const hide = !nidusList.value[index].hide;
    nidusList.value[index].hide = hide;
    nidusList.value[index].child.forEach(
      (subItem: VideoType.NidusSubItem, subIndex: number) => {
        subItem.child.forEach(
          (thirdItem: VideoType.NidusThirdItem, thirdIndex: number) => {
            handleShowOrHide(thirdItem, hide);
          }
        );
        subItem.hide = hide;
      }
    );
    //单帧列表的全部隐藏
    videoStore.hideAllSingle(index, hide);
    //更新影像
    const singleList = videoStore.getSingleAnnoListBySuid(currentSeriesUid.value);
    singleList.map((it: any) => {
      handleShowOrHide(it, it.hide);
    });
  });
  bus.on("Header.changeGroupIndex", changeGroupIndex);
  bus.on("Cornerstone.singleClick", singleClick);

  //字典
  // lesionSetting.value = await VideoApi.lesionConfig({ page: 1, pageSize: 1000000 });
  // commonConfig.value = await VideoApi.commonConfig({});
  // dictList.value = await VideoApi.childQuery();
  //任务信息&项目信息
  // taskInfo.value = await VideoApi.taskRead({ taskId: taskId.value });
  const projectInfoRes = await VideoApi.projectRead(+taskId.value);
  projectInfo.value = projectInfoRes.data?.data;

  // handleProjectInfo();

  // 获取废片集合
  // const discardData = await VideoApi.fetchDiscardList(taskInfo.value.projectId);
  // discardData && processData(discardData);

  //标注工具数据
  // setToolData(taskInfo.value.data.lesionList);
  //其他工具
  // setOtherTools(taskInfo.value);
  if (isCreate) {
    //开始任务
    await setSeriesInfoInfoIsStart();
  }
  if (route.query.dataType) {
    //once or multiple
    //从session中拿
    const taskInfo = JSON.parse(sessionStorage.getItem("task_info") || "{}");
    serialNumber.value = taskInfo.groupId;
  }
  //编辑、查看、已提交序列
  await setSeriesGroupList();
  await setVideoList();

  nextTick(() => {
    setToolDisabled();
  });

  setLoading(false);
});

function handleComponentData(subItem: any) {
  if (subItem.componentParameter) {
    const componentParameter = JSON.parse(subItem.componentParameter);
    const { hasnull } = componentParameter;
    if (hasnull === true) {
      const componentData = JSON.parse(subItem.componentData);
      componentData.push({
        text: "无",
        code: "-1",
      });
      subItem.componentData = JSON.stringify(componentData);
    }
  }
}

function handleProjectInfo() {
  const { annotationItemList, imageAnnotationList } = projectInfo.value;
  imageAnnotationList.forEach((item: any) => {
    item.annotationItemList.forEach((subItem: any) => {
      handleComponentData(subItem);
    });
  });
  annotationItemList.forEach((subItem: any) => {
    handleComponentData(subItem);
  });
}

function setLoading(flag: any) {
  filmReadStore.loading = flag;
}

function singleClick(uuid: any) {
  const [isCreate, index, subIndex, thirdIndex] = getLabelInfoByUuid(uuid);
  if (isCreate) return;
  if (thirdIndex !== -1) {
    //帧段
    const thirdItem: VideoType.NidusThirdItem =
      nidusList.value[index].child[subIndex].child[thirdIndex];
    utilHooks.lesionEvent.frameActive(
      nidusList.value[index].child[subIndex].id as number
    ); //高亮帧段
    utilHooks.lesionEvent.lesionSetActive(thirdItem.id.toString()); //高亮列表
    //高亮图像中的
    setNidusActive(index, subIndex, thirdIndex, !thirdItem.isActive);
    // setFrameActive(0, 0, true);如果单帧是否反选帧段
    setNidusListColor(index, subIndex, thirdIndex, thirdItem.isActive);
    // scrollToView(`${thirdItem.nidusName}-${thirdItem.id}`);
  } else {
    //单帧
    const singleItem = videoStore.getSingleItemByUuid(uuid);
    utilHooks.lesionEvent.frameActive(0); //单帧时切换tab
    utilHooks.lesionEvent.lesionSetActive(singleItem.id.toString());
    //高亮图像中的
    videoStore.setSingleSelected(currentSeriesUid.value, singleItem.id);
    setSingleColor(singleItem, singleItem.isActive);
    // scrollToView(`${singleItem.nidusName}-${singleItem.id}`);
  }
}

provide("singleClick", singleClick);

function scrollToView(id) {
  nextTick(() => {
    const selected = document.getElementById(id);
    selected &&
      selected.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" });
  });
}

async function changeGroupIndex(index: any) {
  let value = groupIndex.value + index;
  if (value < 0) value = 0;
  if (value > seriesGroupList.value.length - 1) value = seriesGroupList.value.length - 1;
  groupIndex.value = value;
  videoList.value = [];
  nidusList.value = [];
  setLoading(true);
  await setSeriesGroupList();
  // await setSeriesInfoBySeriesGroup();
  await setVideoList();
  setLoading(false);
}

//开始任务获取序列
async function setSeriesInfoInfoIsStart() {
  const res: any = await VideoApi.userSeriesGet({
    taskId: Number(taskId.value),
  });
  //让接口返回一个groupId
  serialNumber.value = res.groupId;
  seriesInfo.value = {
    sarIdList: res?.sarIdList || [],
  };
}

async function setSeriesInfoBySeriesGroup(arId: any) {
  const res: any = await VideoApi.getSeriesResult({
    arId, //todo 从前面的序列中获取
  });
  seriesInfo.value = {
    sarIdList: (res.list || []).map((item: any) => item.id),
  };
}
//任务下的所有检查（序列组）
async function setSeriesGroupList() {
  const params = {
    page: 1,
    pageSize: 10000,
    taskId: +taskId.value,
    userId: +submitUserId.value || +userId.value,
  };
  const result: any = await VideoApi.getSeiesList(params);
  seriesGroupList.value = result.data?.list || [];
  if (serialNumber.value) {
    groupIndex.value = seriesGroupList.value.findIndex(
      (item: any) => item.groupId === serialNumber.value
    );
  }
  setDiscard();
}

function setDiscard() {
  const currnetSeriesInfo = seriesGroupList.value[groupIndex.value];
  if (currnetSeriesInfo) {
    filmReadRight.rejectFilmVisible = currnetSeriesInfo.discarded;
    const discard = scrapList.value.find(
      (item: any) => item.value === currnetSeriesInfo.discardCode
    );
    filmReadRight.rejectFilmValue = `${
      currnetSeriesInfo.discardReason ? currnetSeriesInfo.discardReason + "," : ""
    }${discard?.name || ""} `;
  }
}

//设置大征像数据
async function setBigSignContainer() {
  if (videoList.value.length > 0) {
    const { sarId } = videoList.value[0];
    await setSeriesResultInfo(sarId);
    setBigSign();
  }
}

//获取病灶名
function getLesionName(list: any[], value: string, subValue: string) {
  const item = list.find((item: any) => item.value === value);
  if (!item) return "";
  const subItem = (item.children || []).find(
    (subItem: any) => subItem.value === subValue
  );
  return subItem ? subItem.name : "";
}

//获取帧段内的病灶列表
function getLabeList(type: string, list: any[]) {
  const array: VideoType.ToolItemLabelListItem[] = [];
  list.forEach((item: any) => {
    const { toolList } = item;
    const index = toolList.findIndex((subItem: any) => subItem === type);
    if (index > -1) {
      array.push({
        name: getLesionName(dictList.value, "LESION", item.type),
        type: item.type,
        color: item.colour,
        id: item.id,
        annotationItemList: item.annotationItemList || [],
        imageAnnotationToolId: toolList[index].id,
        imageAnnotationId: toolList[index].imageAnnotationId,
      });
    }
  });
  return array;
}

// 设置标注工具数据
const setToolData = (list: any[]) => {
  const array: VideoType.ToolItem[] = [];
  list.forEach((item: any) => {
    const { toolList } = item;
    toolList.forEach((subItem: any) => {
      const index: number = array.findIndex(
        (arrayItem: any) => arrayItem.type === subItem
      );
      if (index === -1) {
        const { name, toolName, iconName } = DataTransfer.getToolInfo(subItem);
        if (!name) return;
        array.push({
          name,
          toolName,
          iconName,
          value: "",
          active: false,
          type: subItem,
          // labelList: getLabeList(subItem, list),
          disabled: isView,
        });
      }
    });
  });
  toolData.value = array;
};

const setOtherTools = (pm: any) => {
  const { needTrace } = pm;
  if (needTrace) {
    toolData.value.push({
      name: "追踪",
      toolName: "needTrace",
      iconName: "zhuizong",
      disabled: false,
      isSeleted: false,
      active: false,
      value: "",
    });
  }
};

// 获取大征象数据
function getBigSignData(annotationItemResultList: any): VideoType.SeriesForm[] {
  let data: VideoType.SeriesForm[] = [];
  projectInfo.value.annotationItemList.forEach((item: any) => {
    const resultItem = (annotationItemResultList || []).find(
      (subItem: any) => item.componentId === subItem.formComponentId
    );
    const value = getSignResultView(item.componentType, resultItem);
    data.push({
      required: item.required,
      field: item.componentId,
      label: item.componentName,
      message: "",
      type: item.componentType,
      value,
    });
  });
  return data;
}

// 设置影像序列数据、病灶列表数据
async function setVideoList() {
  const currentGroup = seriesGroupList.value[groupIndex.value];
  const seriesList = currentGroup.seriesAnnoList;
  if (!Array.isArray(seriesList)) return;
  const list: VideoItem[] = [];
  const _nidusList: any = [];
  const _singleList: any = [];
  for (let index = 0; index < seriesList.length; index++) {
    const { arId, seriesUid } = seriesList[index];
    //序列病灶数据
    const seriesResult: any = await VideoApi.readSeriesResult({
      arId,
    });
    //序列视频数据
    const frameInfo: any = await VideoApi.videoFrameInfo({
      seriesUid: seriesUid,
    });
    // const seriesForm: VideoType.SeriesForm[] = getBigSignData(seriesResult.annotationItemResultList);
    const seriesInfo = seriesResult.data;
    _nidusList.push({
      id: seriesUid,
      sarId: arId,
      child: (seriesInfo.groupList || []).map((item: any) => {
        const info = item.info ? JSON.parse(item.info) : {};
        let subChild: any = {
          id: item.id,
          name: "帧段",
          endIndex: info.endFrame,
          startIndex: info.startFrame,
          slideValues: [info.startFrame, info.endFrame],
          child: getLabelChild(item.id, seriesInfo),
          uuid: item.id,
          isOpen: false,
          algProcessed: item.algProcessed, //是否追踪过
        };
        return subChild;
      }),
      // seriesForm: seriesForm,
      currentVideoIndex: currentVideoIndex.value,
      hide: false,
    });
    //所有序列的单帧列表
    _singleList.push({
      id: seriesUid,
      sarId: arId,
      // seriesForm: seriesForm,
      currentVideoIndex: currentVideoIndex.value,
      list: getSingleChild(seriesInfo),
    });
    const {
      framesZipUrl,
      frameRate,
      imageHeight,
      imageWidth,
      totalFrame,
    } = frameInfo.data;
    //获取图片
    const images: string[] = await getImages(framesZipUrl);
    list.push({
      seriesUid: seriesUid,
      isActive: index === 0 ? true : false,
      images: images, //getiMAGE( ),
      sarId: arId,
      frameRate: frameRate,
      imageHeight: imageHeight,
      imageWidth: imageWidth,
      totalFrame: totalFrame,
    });
  }
  // 生成单帧标注列表数据
  videoStore.singleAnnoList = _singleList; //单帧数据 todo 从哪里取接口还是store
  videoList.value = list; //检查下的所有序列数据
  nidusList.value = _nidusList; //帧段、病灶数据 todo 从哪里取接口还是store
}

//刷新病灶列表，不包括图像数据
async function setNidusList() {
  const currentGroup = seriesGroupList.value[groupIndex.value];
  const seriesList = currentGroup.seriesAnnoList;
  if (!Array.isArray(seriesList)) return;
  const _nidusList: any = [];
  const _singleList: any = [];
  for (let index = 0; index < seriesList.length; index++) {
    const { arId, seriesUid } = seriesList[index];
    //序列病灶数据
    const seriesResult: any = await VideoApi.readSeriesResult({
      arId,
    });
    const seriesInfo = seriesResult.data;
    _nidusList.push({
      id: seriesUid,
      sarId: arId,
      child: (seriesInfo.groupList || []).map((item: any) => {
        const info = item.info ? JSON.parse(item.info) : {};
        let subChild: any = {
          id: item.id,
          name: "帧段",
          endIndex: info.endFrame,
          startIndex: info.startFrame,
          slideValues: [info.startFrame, info.endFrame],
          child: getLabelChild(item.id, seriesInfo),
          uuid: item.id,
          isOpen: false,
          algProcessed: item.algProcessed, //是否追踪过
        };
        return subChild;
      }),
      currentVideoIndex: currentVideoIndex.value,
      hide: false,
    });
    //所有序列的单帧列表
    _singleList.push({
      id: seriesUid,
      sarId: arId,
      currentVideoIndex: currentVideoIndex.value,
      list: getSingleChild(seriesInfo),
    });
  }
  // 生成单帧标注列表数据
  videoStore.singleAnnoList = _singleList; //单帧数据 todo 从哪里取接口还是store
  nidusList.value = _nidusList; //帧段、病灶数据 todo 从哪里取接口还是store
}

function getiMAGE(images: any) {
  let array: any = [];
  const _image: any = JSON.parse(JSON.stringify(images.slice(0, 100)));
  for (let i = 0; i < 25; i++) {
    array.push(..._image);
  }
  return array;
}

//某序列下单帧列表
function getSingleChild(seriesResult: any) {
  const { lesionResultList } = seriesResult;
  if (!Array.isArray(lesionResultList)) return [];
  const singleDataList = lesionResultList.filter((it: any) => it.groupId === 0);
  return singleDataList.map((item: any) => {
    const {
      name,
      toolName,
      getLabelIndex,
      modeltoctrenderdata,
    } = DataTransfer.getToolInfo(item.tool);
    const result = JSON.parse(item.result);
    const data = modeltoctrenderdata(toRaw(result.data));
    const labelIndex = getLabelIndex(result.data);
    const imageAnnoForm = []; //getSmallSignData(item.imageAnnotationId, seriesResult, item.id);
    const color = item.color || getColor(item.lesion); //todo 颜色优先值：病灶自带>任务配置
    data.color = color;
    return {
      labelIndex,
      name,
      nidusName: getNidusName(item.lesion),
      toolName,
      data: data,
      id: item.id,
      isActive: false,
      color,
      resultGroupUuid: item.groupId,
      // imageAnnotationId: item.imageAnnotationId,
      // imageAnnotationToolId: item.imageAnnotationToolId,
      uuid: "",
      hide: false,
      imageAnnoForm,
      alg: item.alg || false,
    };
  });
}

//组装单帧列表的一项
function createSingleItem(addedItem: any) {
  /*const { lesionResultList } = seriesResult;
  const singleDataList = lesionResultList.filter((it: any) => it.groupId === 0);
  const addedItem = singleDataList.find((it: any) => it.id === addedId);*/
  const { name, toolName, getLabelIndex, modeltoctrenderdata } = DataTransfer.getToolInfo(
    addedItem.tool
  );
  const result = JSON.parse(addedItem.result);
  result.data.uuid = addedItem.uuid;
  const data = modeltoctrenderdata(toRaw(result.data));
  const labelIndex = getLabelIndex(result.data);
  const color = addedItem.color; //getColor(addedItem.imageAnnotationId);
  data.color = color;
  const imageAnnoForm = []; /*getSmallSignData(
    addedItem.imageAnnotationId,
    seriesResult,
    addedItem.id
  );*/
  return {
    labelIndex,
    name,
    nidusName: getNidusName(addedItem.lesion),
    toolName,
    data: data,
    id: addedItem.id,
    isActive: false,
    color,
    // resultGroupUuid: addedItem.resultGroupUuid,
    // imageAnnotationId: addedItem.imageAnnotationId,
    // imageAnnotationToolId: addedItem.imageAnnotationToolId,
    uuid: "", // 废弃，用id?
    hide: false,
    imageAnnoForm,
    alg: addedItem.alg || false,
  };
}

//帧段下列表
function getLabelChild(groupId: string, seriesResult: any) {
  const { lesionResultList } = seriesResult;
  if (!Array.isArray(lesionResultList)) return [];
  const list = JSON.parse(JSON.stringify(lesionResultList));
  let array: VideoType.NidusThirdItem[] = [];
  list.forEach((item: any) => {
    if (item.groupId === groupId && item.result) {
      const result = JSON.parse(item.result);
      const {
        name,
        toolName,
        getLabelIndex,
        modeltoctrenderdata,
      } = DataTransfer.getToolInfo(item.tool);
      const data = modeltoctrenderdata(toRaw(result.data));
      const labelIndex = getLabelIndex(result.data);
      const imageAnnoForm = []; //getSmallSignData(item.imageAnnotationId, seriesResult, item.id);
      const color = item.color || getColor(item.lesion);
      data.color = color;
      array.push({
        labelIndex,
        name,
        nidusName: getNidusName(item.lesion),
        toolName,
        data: data,
        id: item.id,
        isActive: false,
        color,
        resultGroupUuid: item.groupId,
        // imageAnnotationId: item.id,
        // imageAnnotationToolId: item.imageAnnotationToolId,
        toolCode: item.lesion,
        uuid: "",
        hide: false,
        imageAnnoForm,
        alg: item.alg || false,
      });
    }
  });
  //排序：自画矩形-自画其他-算法追踪
  const arr1: any[] = [],
    arr2: any[] = [],
    arr3: any[] = [],
    arr4: any[] = [];
  array.forEach((it) => {
    const { alg, toolName } = it;
    if (toolName === "RectangleRoi" && !alg) {
      arr1.push(it);
    } else if (toolName !== "RectangleRoi" && !alg) {
      arr2.push(it);
    } else if (toolName === "RectangleRoi" && alg) {
      arr3.push(it);
    } else {
      arr4.push(it);
    }
  });
  return arr1.concat(arr2, arr3, arr4);
}

function getColor(lesionCode: number) {
  const lesionList = projectInfo?.value?.annoInfo?.lesionList || [];
  const item = lesionList.find((item: any) => item.lesionValue === lesionCode);
  return item?.color || null;
}

function getNidusName(lesionType: number) {
  const lesionMap = filmReadStore.dictionaryData.lesionList;
  return lesionMap[lesionType]?.name;
}

//解压zip，并且转换成base64图片
async function getImages(url: string): Promise<any> {
  const zipResp = await JSZipUtils.getBinaryContent(url);
  const jsZip = new JsZip();
  const imgData: any = await jsZip.loadAsync(zipResp);
  const keys = Object.keys(imgData.files);
  zipDataSort(keys || []);
  const images: any = [];
  for (let i = 0; i < keys.length; i++) {
    const key = keys[i];
    const base64Img = await imgData.file(key).async("base64");
    const suffixName = key.split(".")[0];
    const imgUrl = `data:image/${suffixName};base64,${base64Img}`;
    images.push(imgUrl);
  }
  return images;
}

// 解压的数据排序
const zipDataSort = (keys: string[]) => {
  keys.sort((a: string, b: string): any => {
    const regex = /(\d)+/g;
    const value1 = a.match(regex) ? Number((a.match(regex) as any)[0]) : 0;
    const value2 = b.match(regex) ? Number((b.match(regex) as any)[0]) : 0;
    if (!isNaN(value1) && !isNaN(value2)) {
      return value1 - value2;
    } else {
      console.error("数据错误");
    }
  });
};

//设置帧端眼睛隐藏
function setFrameShowOrHide(index: number, subIndex: number, hide: boolean) {
  nidusList.value[index].child.forEach((subItem: VideoType.NidusSubItem) => {
    subItem.hide = true;
  });
  if (!hide) {
    nidusList.value[index].child[subIndex].hide = false;
  }
}

//设置帧端眼睛 睁开或闭上
function setNidusShowOrHide(
  index: number,
  subIndex: number,
  thirdIndex: number,
  hide: boolean
) {
  nidusList.value[index].child.forEach((subItem: VideoType.NidusSubItem) => {
    subItem.child.forEach((thirdItem: VideoType.NidusThirdItem) => {
      thirdItem.hide = true;
    });
  });
  if (!hide) {
    nidusList.value[index].child[subIndex].child[thirdIndex].hide = false;
  }
}

//查看帧段下病灶是否全部隐藏
function isNidusHideEvery(index: number, subIndex: number) {
  const isHideEvery = nidusList.value[index].child[subIndex].child.every(
    (thirdItem: VideoType.NidusThirdItem) => thirdItem.hide
  );
  return isHideEvery;
}

//当前序列是否全部隐藏
function isCurrentSeriesDidusHideEvery(index: number) {
  let isHideEvery = true;
  nidusList.value[index].child.forEach(
    (subItem: VideoType.NidusSubItem, subIndex: number) => {
      const isHide = isNidusHideEvery(index, subIndex);
      if (!isHide) {
        isHideEvery = false;
      }
    }
  );
  return isHideEvery;
}
//所有病灶的隐藏,包括帧段、单帧
function hideAll(ifShow: boolean) {
  //todo
  //帧段
  nidusList.value[currentVideoListIndex.value].child.map((frameItem, frameIdx) => {
    frameItem.child.map((nidusItem, nidusIdx) => {
      handleShowOrHide(nidusItem, !ifShow);
    });
  });
  //单帧
  videoStore.currentSingleList.map((item: any) => {
    handleShowOrHide(item, !ifShow);
  });
}
//点击显示隐藏按钮图标
function nidusToggleShowOrHide(indexs: number[]) {
  const [index, subIndex, thirdIndex] = indexs;
  const subItem = nidusList.value[index].child[subIndex];
  if (thirdIndex === null) {
    //帧段上的显示或隐藏
    subItem.hide = !subItem.hide;
    subItem.child.forEach((thirdItem: VideoType.NidusThirdItem, _thirdIndex: number) => {
      handleShowOrHide(thirdItem, subItem.hide);
    });
  } else {
    //病灶上的显示或隐藏
    const thirdItem = subItem.child[thirdIndex];
    handleShowOrHide(thirdItem, !thirdItem.hide);
  }
  //当前帧段的所有帧都闭眼
  subItem.hide = isNidusHideEvery(index, subIndex);
  nidusList.value[index].hide = isCurrentSeriesDidusHideEvery(index);
}

//单帧显示、隐藏
const singleEyeClick = (thirdItem: any) => {
  videoStore.toggleSingleHide(thirdItem.id);
  handleShowOrHide(thirdItem, thirdItem.hide);
};

function handleShowOrHide(thirdItem: VideoType.NidusThirdItem, hide: boolean) {
  thirdItem.hide = hide;
  const name = thirdItem.hide ? "VideoLabel.hideNidus" : "VideoLabel.showNidus";
  bus.emit(name, {
    thirdItem: thirdItem,
  });
}

provide("handleShowOrHide", handleShowOrHide);

function noIsActiveInNidusList() {
  let noIsActive = false;
  currentNidus.child.forEach((subItem: VideoType.NidusSubItem) => {
    if (noIsActive) return;
    noIsActive = subItem.child.every(
      (thirdItem: VideoType.NidusThirdItem) => !thirdItem.isActive
    );
  });
  return noIsActive;
}

const removeFlag = ref(false);
//删除病灶组
const removeNidus = async (indexs: any) => {
  const [index, subIndex, thirdIndex] = indexs;
  const item = nidusList.value[index];
  const subItem = item.child[subIndex];
  try {
    if (removeFlag.value) return;
    removeFlag.value = true;
    if (thirdIndex === null) {
      // 有标注的病灶不允许删除病灶组？可以删除
      if (subItem.child.length) {
        subItem.child.map((thirdItem) => {
          bus.emit("VideoLabel.removeNidus", {
            thirdItem,
          });
        });
      }
      const model: VideoType.IdModel = {
        id: subItem.id,
      };
      // await VideoApi.deleteIarGroup(model); todo
      item.child.splice(subIndex, 1);
      /*if (noIsActiveInNidusList()) {
        setBigSign();
      }*/
    } else {
      //病灶
      const thirdItem = subItem.child[thirdIndex];
      /*await VideoApi.deleteAnnoResult({
        id: thirdItem.id,
      });*/
      bus.emit("VideoLabel.removeNidus", {
        thirdItem,
      });
      subItem.child.splice(thirdIndex, 1);
      /*if (thirdItem.isActive) {
        setBigSign();
      }*/
    }
    removeFlag.value = false;
  } catch (error) {
    removeFlag.value = false;
  }
};

//修改病灶组
async function nidusIndexChange(data: any) {
  let { id, startIndex, endIndex, cellWidth } = data;
  const nidusItem = nidusList.value.find(
    (item: any) => item.id === currentSeriesUid.value
  ) as VideoType.NidusItem;
  if (nidusItem) {
    const currentChild: any = nidusItem.child.find((item: any) => item.id === id);
    if (!currentChild) return;
    const labelindexs = currentChild.child.map((item: any) => item.labelIndex);
    if (Array.isArray(labelindexs) && labelindexs.length > 0) {
      const min = Math.min(...labelindexs);
      const max = Math.max(...labelindexs);
      // 开始index值(0开始) > 最小帧的位置（从1开始）
      if (startIndex > min) {
        currentChild.startIndex = min;
        currentChild.slideValues = [(min - 1) * cellWidth, currentChild.slideValues[1]];
      } else {
        currentChild.startIndex = startIndex;
        currentChild.slideValues = [
          (startIndex - 1) * cellWidth,
          currentChild.slideValues[1],
        ];
      }
      if (endIndex < max) {
        currentChild.endIndex = max;
        currentChild.slideValues = [currentChild.slideValues[0], (max - 1) * cellWidth];
      } else {
        currentChild.endIndex = endIndex;
        currentChild.slideValues = [
          currentChild.slideValues[0],
          (endIndex - 1) * cellWidth,
        ];
      }
    } else {
      currentChild.startIndex = startIndex;
      currentChild.endIndex = endIndex;
      currentChild.slideValues = [
        (startIndex - 1) * cellWidth,
        (endIndex - 1) * cellWidth,
      ];
    }
    const info = {
      startFrame: currentChild.startIndex,
      endFrame: currentChild.endIndex,
    };
    const model = {
      id: currentChild.id,
      info: JSON.stringify(info),
    };
    await VideoApi.updateIarGroup(model);
    //todo 更新左边列表中的帧段信息
    const updateItem = {
      id: currentChild.id,
      info,
    };
    utilHooks.lesionEvent.frameUpdate(updateItem);
    setToolDisabled();
  }
}

//验证帧是否合法
function verificationIndex(videoIndex: number, currentNidus: any) {
  let value: boolean = true;
  currentNidus.child.forEach((item: any) => {
    if (videoIndex < item.startIndex) {
      value = false;
    }
  });
  return value;
}

// 点击计时器，设置开始帧、结束帧
const handleClickTimer = async (data: any) => {
  const { isStart, cellWidth } = data;
  const videoIndex = data.videoIndex + 1;
  /*const currentNidus = nidusList.value.find(
    (item: any) => item.id === currentSeriesUid.value
  );*/
  const currentNidusIndex = nidusList.value.findIndex(
    (item: any) => item.id === currentSeriesUid.value
  );
  if (currentNidus.value) {
    const len = currentNidus.value.child.length;
    if (isStart) {
      //开始帧
      currentNidus.value.child.push({
        name: "帧段",
        id: 0,
        uuid: "",
        startIndex: videoIndex,
        endIndex: null,
        child: [],
        slideValues: [data.videoIndex * cellWidth],
        isOpen: false,
        hide: false,
        isActive: false,
        algProcessed: false,
      });
      console.log(nidusList.value, "nidusList");
    } else {
      //结束帧
      const currentChild: any = currentNidus.value.child[len - 1];
      //结束帧必须大于等于开始帧
      if (videoIndex < currentChild.startIndex) return;
      const info = {
        startFrame: currentChild.startIndex,
        endFrame: videoIndex,
      };
      const model: VideoType.ReateIarGroupModel = {
        arId: currentNidus.value.sarId,
        type: GroupType,
        info: JSON.stringify(info),
      };
      const res: any = await VideoApi.reateIarGroup(model);

      currentChild.id = res.data?.id;
      // currentChild.uuid = res.data.uuid;
      currentChild.endIndex = videoIndex;
      currentChild.slideValues[1] = data.videoIndex * cellWidth;
      //todo 左边列表数据更新
      const frameItem = {
        id: currentChild.id,
        info,
        type: GroupType,
        taskId: taskId.value,
        arId: model.arId,
      };
      utilHooks.lesionEvent.frameAdd(frameItem as any);
      // 聚焦当前帧段
      setNidusActive(currentNidusIndex, 0, 0, false);
      setFrameActive(currentNidusIndex, len - 1, true);
      //setBigSign();// todo
      setToolDisabled(); //todo
    }
  }
};

const cellWidthObj = ref<any>({});

function slideChange(dataArray: any[]) {
  const [cellWidth, seriesUid] = dataArray;
  cellWidthObj.value[seriesUid] = cellWidth;
  const item = nidusList.value.find((item: VideoType.NidusItem) => item.id === seriesUid);
  if (item) {
    item.child.forEach((subItem: VideoType.NidusSubItem) => {
      subItem.slideValues = [subItem.startIndex, subItem.endIndex].map(
        (index: number | null) => {
          return ((index as number) - 1) * cellWidth;
        }
      );
    });
  }
}

//监听当前帧变化
watch(
  () => currentVideoIndex,
  () => {
    setToolDisabled();
    nextTick(() => {
      setCurrnetVideoIndex();
    });
  },
  {
    deep: true,
  }
);

function setCurrnetVideoIndex() {
  currentNidus.value.currentVideoIndex = currentVideoIndex.value;
}

const currnetImageAnnotationId = ref(0);
const currentImageAnnotationToolId = ref("");
const currentColor = ref("");
const currentNidusName = ref("");

const currentToolName = ref("");
// 标注工具发生变化
const toolsChange = (changeData: any) => {
  const { toolName } = changeData;
  currentToolName.value = toolName;
  if (toolName === "Wwwc" || toolName === "") {
    bus.emit("VideoLabel.wwwcToolsChange", changeData);
  } else {
    currentColor.value = changeData.color;
    currentNidusName.value = changeData.nidusName;
    currnetImageAnnotationId.value = changeData.imageAnnotationId;
    currentImageAnnotationToolId.value = changeData.imageAnnotationToolId;
    bus.emit("VideoLabel.labelToolsChange", changeData);
  }
};

//通过uuid来判断是新建还是编辑(帧段和单帧列表中都查不到才是新建，否则返回位置)
function getLabelInfoByUuid(uuid: string): [boolean, number, number, number] {
  let [isCreate, index, subIndex, thirdIndex] = [true, -1, -1, -1];
  //单帧列表的逻辑，查看uuid是否存在判断新增or编辑
  const singleList = videoStore.getSingleAnnoListBySuid(currentSeriesUid.value);
  const _index = singleList.findIndex((item: any) => item.data.uuid === uuid);
  const isCreateSingle = _index > -1 ? false : true;
  const indexSingle = _index;
  //帧段
  const currentIndex = nidusList.value.findIndex(
    (item: any) => item.id === currentSeriesUid.value
  );
  if (currentIndex > -1) {
    const currentItem = nidusList.value[currentIndex];
    currentItem.child.forEach((_subItem: VideoType.NidusSubItem, _subIndex: number) => {
      _subItem.child.forEach(
        (_thirdItem: VideoType.NidusThirdItem, _thirdIndex: number) => {
          if (!isCreate) return;
          if (_thirdItem.data && _thirdItem.data.uuid === uuid) {
            isCreate = false;
            index = currentIndex;
            subIndex = _subIndex;
            thirdIndex = _thirdIndex;
          }
        }
      );
    });
  }
  if (isCreateSingle && isCreate) {
    //都查不到
    return [true, index, 0, 0];
  } else {
    if (!isCreateSingle) return [isCreateSingle, indexSingle, -1, -1];
    if (!isCreate) return [isCreate, index, subIndex, thirdIndex];
  }
  return [isCreate, index, subIndex, thirdIndex];
}

function getLabelInfoByLabelIndex(currentIndex: number) {
  let list: any = [];
  const index = nidusList.value.findIndex(
    (item: any) => item.id === currentSeriesUid.value
  );
  if (index > -1) {
    const item = nidusList.value[index];
    item.child.forEach((subItem: VideoType.NidusSubItem, subIndex: number) => {
      subItem.child.forEach((thirdItem, thirdIndex) => {
        if (thirdItem.labelIndex === currentIndex) {
          list.push({
            item,
            index,
            subItem,
            subIndex,
            thirdItem,
            thirdIndex,
          });
        }
      });
    });
  }
  return list;
}

//删除标注
async function remove(dataArray: any) {
  const [uuid] = dataArray;
  const [isCreate, index, subIndex, thirdIndex] = getLabelInfoByUuid(uuid);
  removeNidus([index, subIndex, thirdIndex]);
}

// 编辑单帧标注的框
async function singleMeasurementModified(dataArray: any) {
  try {
    const [toolType, toolData] = dataArray;
    const singleAnnoItem = videoStore.singleAnnoList.find(
      (item: any) => item.id === currentSeriesUid.value
    );
    const thirdItem = singleAnnoItem.list.find(
      (it: any) => it.data.uuid === toolData.uuid
    );
    // 替换缓存中数据
    thirdItem.data = toolData;
    const { ctRenderDataToModel } = DataTransfer.getToolInfo(thirdItem.toolName);
    const result = ctRenderDataToModel(
      toRaw(thirdItem.data),
      currentVideoIndex.value + 1
    );
    const annoUpdateModel: VideoType.AnnoUpdateModel = {
      alrId: thirdItem.id,
      imageAnnotationToolId: thirdItem.imageAnnotationToolId,
      result: JSON.stringify(result),
    };
    await VideoApi.annoUpdate(annoUpdateModel);
    utilHooks.lesionEvent.videoLesionUpdate(annoUpdateModel.alrId as number, { result });
    await setLoding();
  } catch (error) {
    await setLoding();
  }
}

//更新标注
async function measurementModified(dataArray: any) {
  // 查询是否在单帧列表里,区分单帧标注
  const [toolType, toolData] = dataArray;
  const singleList = videoStore.getSingleAnnoListBySuid(currentSeriesUid.value);
  const isSingle = singleList.find((item: any) => item.data.uuid === toolData.uuid);
  if (isSingle != undefined) {
    await singleMeasurementModified(dataArray);
    return;
  }
  try {
    const [toolName, data] = dataArray;
    const [isCreate, index, subIndex, thirdIndex] = getLabelInfoByUuid(data.uuid);
    if (thirdIndex > -1) {
      const thirdItem = nidusList.value[index].child[subIndex].child[thirdIndex];
      thirdItem.data = data;
      const { ctRenderDataToModel } = DataTransfer.getToolInfo(thirdItem.toolName);
      const result = ctRenderDataToModel(
        toRaw(thirdItem.data),
        currentVideoIndex.value + 1
      );
      const annoUpdateModel: VideoType.AnnoUpdateModel = {
        alrId: thirdItem.id,
        imageAnnotationToolId: thirdItem.imageAnnotationToolId,
        result: JSON.stringify(result),
      };
      await VideoApi.annoUpdate(annoUpdateModel);
      utilHooks.lesionEvent.videoLesionUpdate(annoUpdateModel.alrId as number, {
        result,
      });
    }
    await setLoding();
    console.log("修改完本地数据", filmReadStore.dictionaryData.imageDataList);
  } catch (error) {
    console.warn(error);
    await setLoding();
  }
}

function isFreehandDataError(data: any) {
  const { handles } = data;
  const { points } = handles;
  return !Array.isArray(points) || (Array.isArray(points) && points.length <= 1);
}

function isRectangleDataError(data: any) {
  const { handles } = data;
  const { end, start } = handles;
  const base = 5;
  return Math.abs(start.x - end.x) <= base && Math.abs(start.y - end.y) <= base;
}

async function setLoding() {
  new Promise((resolve) => {
    setTimeout(() => {
      setLoading(false);
    }, 300);
  });
}

//新建和编辑都会走
async function completed(array: any) {
  if (filmReadStore.loading) return;
  setLoading(true);
  const [toolName, measurementData, isRectangle, isFreehand] = array;
  const [isCreate, index, subIndex, thirdIndex] = getLabelInfoByUuid(
    measurementData.uuid
  );
  if (isFreehand && isFreehandDataError(measurementData)) {
    await setLoding();
    return;
  }
  if (isRectangle && isRectangleDataError(measurementData)) {
    await setLoding();
    return;
  }
  if (isCreate) {
    measurementAdded(array);
  } else {
    measurementModified(array);
  }
}

//添加单帧标注
async function singleMeasurementAdded(dataArray: any) {
  try {
    const [toolName, data] = dataArray;
    const { name, ctRenderDataToModel, modeltoctrenderdata } = DataTransfer.getToolInfo(
      toolName
    );
    // 1、创建病灶
    const result = ctRenderDataToModel(toRaw(data), currentVideoIndex.value + 1);
    const annoCreateModel: any = {
      // imageAnnotationId: currnetImageAnnotationId.value,
      // imageAnnotationToolId: currentImageAnnotationToolId.value, //标注工具id
      // seriesAnnotationResultId: currentSeriesAnnotationResultId.value, //序列id
      arId: currentToolData.value.arId,
      lesion: currentToolData.value.lesion,
      tool: currentToolData.value.tool,
      result: JSON.stringify(result),
    };
    const res: any = await VideoApi.annoCreate(annoCreateModel);
    //接口失败，删除标注
    if (!res.data?.alrId) {
      await handleFailed(toolName, data);
      return;
    }
    data.id = res.data.alrId;
    // 2、单帧标注列表添加新增项 todo 不用调接口，直接组装
    /*const seriesResult: any = await VideoApi.readSeriesResult({
      arId: currentSarId.value,
    });*/
    // 组装新增单帧数据
    const newItem = {
      uuid: data.uuid, //important
      id: data.id,
      tool: annoCreateModel.tool,
      result: annoCreateModel.result,
      color: currentToolData.value.color,
      lesion: annoCreateModel.lesion,
    };
    const _thirdItem = createSingleItem(newItem);
    /*const { iarGroupList, imageAnnotationResultList } = seriesResult
    const singleList = getSingleChild(seriesResult)
    const singleAnnoItem = videoStore.singleAnnoList.find((item:any) => item.sarId === currentSarId.value)
    singleAnnoItem.list = singleList
    //
    const _thirdItem = singleList.find((it:any) => it.id === res.id)*/
    videoStore.addSingle(currentSeriesUid.value, _thirdItem); //添加列表
    const addedItem = {
      groupId: 0, //单帧的groupId=0
      color: _thirdItem.color,
      id: _thirdItem.id,
      lesion: annoCreateModel.lesion,
      tool: annoCreateModel.tool,
      result: result,
    };
    utilHooks.lesionEvent.lesionAdd(addedItem); //todo 添加左边列表数据
    // videoStore.setSingleSelected(seriesResult.seriesInstanceUid, _thirdItem.id); //列表高亮
    setSingleColor(_thirdItem, true); //影像中高亮
    //3、编辑小征象
    /*const annotationItemResultList = getAnnotationItemResultList(
      currnetImageAnnotationId.value
    );
    const imageResultEditModel: VideoType.imageResultEditModel = {
      annotationItemResultList: annotationItemResultList,
      id: res.id,
    };
    await VideoApi.imageResultEdit(imageResultEditModel);
    setSmallSign(_thirdItem);*/
    await setLoding();
  } catch (err) {
    await setLoding();
  }
}

//添加标注
async function measurementAdded(dataArray: any) {
  //单帧标注，不传resultGroupUuid
  if (videoStore.isSingle) {
    await singleMeasurementAdded(dataArray);
    return;
  }
  try {
    const [toolName, data] = dataArray;
    const [value, index, subIndex] = getCurrentVideoIndexInTimer();
    if (value) {
      const item = nidusList.value[index];
      const { name, ctRenderDataToModel, modeltoctrenderdata } = DataTransfer.getToolInfo(
        toolName
      );
      // 1、创建病灶
      const result = ctRenderDataToModel(toRaw(data), currentVideoIndex.value + 1);
      /*const resultGroupUuid = getResultGroupUuid();
      if (!resultGroupUuid) {
        await setLoding();
        return;
      }*/
      const annoCreateModel: VideoType.AnnoCreateModel = {
        // imageAnnotationId: currnetImageAnnotationId.value,
        // imageAnnotationToolId: currentImageAnnotationToolId.value, //标注工具id
        // seriesAnnotationResultId: currentSeriesAnnotationResultId.value, //序列id
        // resultGroupUuid, //帧段uuid
        groupId: videoStore.activeFrame.id,
        result: JSON.stringify(result),
        arId: currentToolData.value.arId,
        lesion: currentToolData.value.lesion,
        tool: currentToolData.value.tool,
      };
      const res: any = await VideoApi.annoCreate(annoCreateModel);
      //接口失败，删除标注
      if (!res.data?.alrId) {
        await handleFailed(toolName, data);
        return;
      }
      data.id = res.data.alrId;
      data.color = currentToolData.value.color; //设置创建病灶颜色
      /*const seriesResult: any = await VideoApi.readSeriesResult({
        id: item.sarId,
      });*/
      //设置病灶列表数据
      const _thirdItem: any = {
        name,
        nidusName: currentNidusName.value,
        id: data.id,
        // resultGroupUuid: res.resultGroupUuid,
        uuid: "",
        labelIndex: currentVideoIndex.value + 1,
        toolName,
        data: data,
        color: currentToolData.value.color,
        hide: false,
        isActive: true,
        // imageAnnotationId: currnetImageAnnotationId.value,
        // imageAnnotationToolId: currentImageAnnotationToolId.value,
        /*imageAnnoForm: getSmallSignData(
          currnetImageAnnotationId.value,
          seriesResult,
          res.id
        ),*/
      };
      let firstIndex = nidusList.value[index].child[subIndex].child.findIndex(
        (it: VideoType.NidusThirdItem) => {
          return it.alg;
        }
      );
      // let insertIndex:number = -1
      if (firstIndex > -1) {
        // insertIndex = firstIndex
      } else {
        // nidusList.value[index].child[subIndex].child.push(_thirdItem);
        firstIndex = nidusList.value[index].child[subIndex].child.length;
      }
      nidusList.value[index].child[subIndex].child.splice(firstIndex, 0, _thirdItem);
      // const currnetThirdIndex = nidusList.value[index].child[subIndex].child.length - 1;
      // setNidusListActive(index, subIndex, insertIndex);
      setFrameActive(index, subIndex, true);
      setNidusActive(index, subIndex, firstIndex, true);
      const addedItem = {
        groupId: videoStore.activeFrame.id, //帧段id
        color: _thirdItem.color,
        id: _thirdItem.id,
        lesion: annoCreateModel.lesion,
        tool: annoCreateModel.tool,
        result: result,
      };
      utilHooks.lesionEvent.lesionAdd(addedItem); //todo 添加左边列表数据
      setNidusListColor(index, subIndex, firstIndex, true);
      // setMenuOpenIndex();

      //2、编辑小征象
      /*const annotationItemResultList = getAnnotationItemResultList(
        currnetImageAnnotationId.value
      );
      const imageResultEditModel: VideoType.imageResultEditModel = {
        annotationItemResultList: annotationItemResultList,
        id: res.id,
      };
      await VideoApi.imageResultEdit(imageResultEditModel);
      setSmallSign(_thirdItem);*/
      await setLoding();
    } else {
      //创建失败,删除标注
      await handleFailed(toolName, data);
      return;
    }
  } catch (error) {
    console.warn(error);
    await setLoding();
  }
}

async function handleFailed(toolName: any, data: any) {
  await setLoding();
  const failedThirdItem = {
    toolName: toolName,
    data: {
      uuid: data.uuid,
    },
  };
  bus.emit("VideoLabel.removeNidus", { thirdItem: failedThirdItem });
}

//通过currnetImageAnnotationId，去项目接口里获取小征象数据
function getAnnotationItemResultList(imageAnnotationId: number | string) {
  const list = JSON.parse(JSON.stringify(toRaw(projectInfo.value.imageAnnotationList)));
  const listIndex = list.findIndex((item: any) => item.id === imageAnnotationId);
  if (listIndex > -1) {
    const result = list[listIndex].annotationItemList.map((listItem: any) => {
      let isDefault;
      if (listItem.componentParameter) {
        isDefault = JSON.parse(listItem.componentParameter).isdefault;
      }
      return {
        annotationItemId: listItem.id,
        formComponentId: listItem.formComponentId,
        result: isDefault === true ? 1 : "",
      };
    });
    return result;
  }
}

const currentSeriesAnnotationResultId = ref("");

watch(
  () => videoList.value,
  () => {
    if (videoList.value.length) {
      const item = videoList.value.find((item: any) => item.isActive);
      currentSeriesAnnotationResultId.value = (item as VideoItem).sarId;
    }
  },
  {
    deep: true,
  }
);

const toolDisabled = ref(false);

//判断当前帧是否在标注的区间，是激活标注工具，不是禁止标注工具
function setToolDisabled() {
  const [value] = getCurrentVideoIndexInTimer();
  toolDisabled.value = isView || !value;
  leftHooks.leftHooksData.videoDisabled = toolDisabled.value;
  if (toolDisabled.value) {
    bus.emit("VideoLabel.toolDisabled", "enabled");
  } else {
    if (currentToolName.value === "Wwwc" || currentToolName.value === "") {
      bus.emit("VideoLabel.toolDisabled", "enabled");
    } else {
      bus.emit("VideoLabel.toolDisabled", "active");
    }
  }
  //控制追踪按钮
  const needTrace = toolData.value.find((item: any) => item.toolName === "needTrace");
  if (needTrace) {
    needTrace.disabled = videoStore.isMulti ? false : true;
  }
}

provide("setToolDisabled", setToolDisabled);

// 判断当前帧是否在标注的区间
function getCurrentVideoIndexInTimer(): [boolean, number, number] {
  if (videoStore.isSingle) return [true, 0, 0]; //单帧标注时
  let [value, index, subIndex] = [false, 0, 0];
  const currentIndex = nidusList.value.findIndex(
    (item: any) => item.id === currentSeriesUid.value
  );
  if (currentIndex > -1) {
    const item = nidusList.value[currentIndex];
    item.child.forEach((_subItem: VideoType.NidusSubItem, _subIndex: number) => {
      const { startIndex, endIndex, isActive } = _subItem;
      if (
        isActive &&
        startIndex &&
        endIndex &&
        currentVideoIndex.value != null &&
        currentVideoIndex.value + 1 >= startIndex &&
        currentVideoIndex.value + 1 <= endIndex
      ) {
        value = true;
        index = currentIndex;
        subIndex = _subIndex;
      }
    });
  }
  return [value, index, subIndex];
}

// 当前图片列表
const currentImageList = computed(() => {
  const item = videoList.value.find((item: any) => item.isActive);
  return item?.images || [];
});

const currentSeriesUid: any = computed(() => {
  const item = videoList.value.find((item: any) => item.isActive);
  videoStore.currentSeriesUid = item?.seriesUid;
  return item?.seriesUid;
});
//当前序列序号
const currentVideoListIndex: any = computed(() => {
  const index = videoList.value.findIndex((item: any) => item.isActive);
  return index;
});

const currentSarId: any = computed(() => {
  const item = videoList.value.find((item: any) => item.isActive);
  return item?.sarId;
});

const currnetSeriesResultInfo: any = ref();

async function setSeriesResultInfo(sarId?: string) {
  const seriesResultInfo: any = await VideoApi.readSeriesResult({
    arId: sarId || currentSarId.value,
  });
  currnetSeriesResultInfo.value = seriesResultInfo;
}

//当前序列帧段信息
const currentNidus: any = computed(() => {
  const item = nidusList.value.find((item: any) => item.id === currentSeriesUid.value);
  return item;
});

/* 视频数据 */
const changeVideoList = async (item: any, index: number) => {
  await setSeriesResultInfo(item.sarId);
  videoList.value.forEach((videoItem: any) => (videoItem.isActive = false));
  videoList.value[index].isActive = true;
  nextTick(() => {
    // currentVideoIndex.value = currentNidus.value.currentVideoIndex;
    setToolDisabled();
    const currentThirdItem = getCurrentThirdItem();
    if (currentThirdItem) {
      // setSmallSign(currentThirdItem); todo
    } else {
      // setBigSign(); todo
    }
    bus.emit("VideoLabel.clickVideoListItem");
    setDiscard();
  });
};

function getCurrentThirdItem() {
  let _thirdItem: any = null;
  currentNidus.value.child.forEach((subItem: VideoType.NidusSubItem) => {
    subItem.child.forEach((thirdItem: VideoType.NidusThirdItem) => {
      if (_thirdItem) return;
      if (thirdItem.isActive) {
        _thirdItem = thirdItem;
      }
    });
  });
  return _thirdItem;
}

// 根据当前帧的位置，去获取当前帧所在帧段的uuid, 创建病灶需要这个参数
function getResultGroupUuid(): string {
  if (!currentNidus.value) return "";
  let resultGroupUuid: string = "";
  currentNidus.value.child.forEach((subItem: VideoType.NidusSubItem) => {
    if (resultGroupUuid) return;
    if (subItem.isActive) {
      resultGroupUuid = subItem.uuid;
    }
  });
  return resultGroupUuid;
}

function getSignResultModel(type: string, value: string | any[]) {
  if (type === "child_select") {
    return Array.isArray(value) ? value.join("@#@") : value;
  }
  if (type === "checkbox") {
    const _value = Array.isArray(value) ? value.join(",") : value;
    return _value;
    // return _value.includes("-1") ? "-1" : _value;
  }
  return value;
}

function getSignResultView(type: string, item: any) {
  if (type === "child_select") {
    return item ? item.result.split("@#@") : [];
  }
  if (type === "checkbox") {
    return item ? item.result.split(",") : [];
  }
  return item ? item.result : "";
}

//大征象
async function bigChang(formData: any) {
  const { form, formOptions } = JSON.parse(JSON.stringify(formData));
  let annotationItemResultList = formOptions.map((item: any) => {
    let result = {};
    if (form[item.componentId] !== "" || form[item.componentId].length !== 0) {
      result = {
        annotationItemId: item.id,
        formComponentId: item.componentId,
        result: getSignResultModel(item.type, form[item.componentId]) || "",
      };
    }
    return result;
  });
  annotationItemResultList = annotationItemResultList.filter(
    (item: { result: any }) => item.result
  );
  currentNidus.value.seriesForm.forEach((item: any) => {
    item.value = form[item.field];
  });
  if (annotationItemResultList.length === 0) return;
  const imageResultEditModel: VideoType.seriesResultEditModel = {
    annotationItemResultList,
    sarIdList: currentSarId.value.toString(),
  };
  await VideoApi.seriesResultEdit(imageResultEditModel);
  setSeriesResultInfo();
}

//小征象变化
async function smallChang(formData: any) {
  const { form, formId, formOptions } = JSON.parse(JSON.stringify(formData));
  let annotationItemResultList = formOptions.map((item: any) => {
    // let result = {};
    // if (form[item.componentId] !== '' || form[item.componentId].length !== 0) {
    const result = {
      annotationItemId: item.id,
      formComponentId: item.componentId,
      result: getSignResultModel(item.type, form[item.componentId]) || "",
    };
    // }
    return result;
  });
  // console.log("annotationItemResultList", annotationItemResultList)
  // annotationItemResultList = annotationItemResultList.filter((item: { result: any; }) => item.result);
  currentNidus.value.child.forEach((subItem: VideoType.NidusSubItem) => {
    subItem.child.forEach((thirdItem: VideoType.NidusThirdItem) => {
      if (thirdItem.id === formId) {
        thirdItem.imageAnnoForm &&
          thirdItem.imageAnnoForm.forEach((formItem: any) => {
            formItem.value = form[formItem.field];
          });
      }
    });
  });
  // 单帧的征象修改情况
  videoStore.currentSingleList.map((item: any) => {
    if (item.id === formId) {
      item.imageAnnoForm.forEach((formItem: any) => {
        formItem.value = form[formItem.field];
      });
    }
  });
  // if(annotationItemResultList.length === 0) return;
  const imageResultEditModel: VideoType.imageResultEditModel = {
    annotationItemResultList,
    id: currentNidusThirdItem.value.id,
  };
  await VideoApi.imageResultEdit(imageResultEditModel);
  setSeriesResultInfo();
}

/**
 * 获取小征象数据
 * @param imageAnnotationId 征象id
 * @param seriesResult 序列结果数据 series_result/read
 * @param id 病灶id
 */
function getSmallSignData(imageAnnotationId: number, seriesResult: any, id: number) {
  const data: VideoType.SeriesForm[] = [];
  const item1 = projectInfo.value.imageAnnotationList.find(
    (item: any) => item.id === imageAnnotationId
  );
  if (item1) {
    item1.annotationItemList.forEach((item2: any, subIndex: number) => {
      // getForm(item2.componentType, item2.componentId);
      let value;
      const item3 = seriesResult.imageAnnotationResultList.find(
        (item: any) => item.id === id
      );
      if (item3) {
        const item4 = (item3.annotationItemResultList || []).find(
          (item4: any) => item4.formComponentId === item2.componentId
        );
        value = getSignResultView(item2.componentType, item4);
      }
      data.push({
        required: item2.required,
        field: item2.componentId,
        label: item2.componentName,
        message: "",
        type: item2.componentType,
        value,
      });
    });
  }
  return data;
}

function getForm(componentType: string, componentId: number) {
  let result: any = {};
  const item = currnetSeriesResultInfo.value.imageAnnotationResultList.find(
    (item: any) => item.id === currentNidusThirdItem.value.id
  );
  if (item) {
    const subItem = (item.annotationItemResultList || []).find(
      (subItem: any) => subItem.formComponentId === componentId
    );
    result = {
      [componentId]: getSignResultView(componentType, subItem),
    };
  }
  return result;
}

const currentNidusThirdItem: any = ref();
provide("currentNidusThirdItem", currentNidusThirdItem);

//设置小征象
function setSmallSign(thirdItem: VideoType.NidusThirdItem) {
  //设置小征象信息
  currentNidusThirdItem.value = thirdItem;
  const { imageAnnotationId } = thirdItem;
  //项目信息
  const item = projectInfo.value.imageAnnotationList.find(
    (item: any) => item.id === imageAnnotationId
  );
  if (item) {
    filmReadRight.currentSubmenuItem = imageAnnotationId as string;
    filmReadRight.currentMiniSeriesSet.formOptions = [];
    let form = {};
    item.annotationItemList.forEach((subItem: any, subIndex: number) => {
      form = {
        ...form,
        ...getForm(subItem.componentType, subItem.componentId),
      };
      getComponentData(
        {
          ...subItem,
          formId: thirdItem.id,
        },
        2
      );
    });
    filmReadRight.currentMiniSeriesSet.form = form;
  }
}

provide("setSmallSign", setSmallSign);

//跳到病灶所在帧并渲染
function changeVideoIndex(thirdItem: any) {
  setToolDisabled();
  bus.emit("VideoLabel.changeVideoIndex", {
    changeVideoIndex: thirdItem.labelIndex - 1,
    labelData: thirdItem.data,
  });
}

//清除某个序列的病灶颜色(多帧)
function setNidusListColor(
  index: number,
  subIndex: number,
  thirdIndex: number,
  isActive: boolean = true
) {
  nidusList.value[index].child.forEach((subItem: VideoType.NidusSubItem) => {
    subItem.child.forEach((thirdItem: VideoType.NidusThirdItem, _thirdIndex: number) => {
      // if(thirdItem.isActive){
      thirdItem.isActive = false;
      setNidusListSingleColor(thirdItem, thirdItem.color);
      // }
    });
  });
  if (isActive) {
    //正选
    //与当前单帧列表中的互斥，先把单帧列表中的标注失活
    passiveAllSingle();
    const thirdItem = nidusList.value[index].child[subIndex].child[thirdIndex];
    thirdItem.isActive = true;
    bus.emit("VideoLabel.setCurrentSelectedUuid", thirdItem.data.uuid);
    setNidusListSingleColor(thirdItem, videoStore.activeColor);
  } else {
    //反选
    const thirdItem = nidusList.value[index].child[subIndex].child[thirdIndex];
    thirdItem.isActive = false;
    bus.emit("VideoLabel.setCurrentSelectedUuid", "");
    setNidusListSingleColor(thirdItem, thirdItem.color);
  }
}

//失活当前序列的所有单帧标注
const passiveAllSingle = () => {
  videoStore.currentSingleList.map((item: any) => {
    // if(item.isActive){
    item.isActive = false;
    bus.emit("VideoLabel.changeStateColor", {
      color: item.color,
      thirdItem: item,
    });
    // }
  });
};
provide("passiveAllSingle", passiveAllSingle);
//设置单帧病灶框的颜色
const setSingleColor = (itemData: any, flag: boolean) => {
  passiveAllSingle();
  //todo 与当前序列的帧段列表中互斥，先把帧段列表中的标注失活
  // flag && setNidusListColor(currentVideoListIndex.value, 0,0 , false);
  //要最后执行，不然不能选中（选中的才能编辑）
  videoStore.currentSingleList.map((item: any) => {
    if (item.id === itemData.id) {
      const color = flag ? videoStore.activeColor : item.color;
      item.isActive = flag;
      bus.emit("VideoLabel.setCurrentSelectedUuid", flag ? item.data.uuid : "");
      bus.emit("VideoLabel.changeStateColor", {
        color,
        thirdItem: item,
      });
    }
  });
};
provide("setSingleColor", setSingleColor);

//设置单个病灶的颜色
function setNidusListSingleColor(thirdItem: VideoType.NidusThirdItem, color: string) {
  bus.emit("VideoLabel.changeStateColor", {
    color,
    thirdItem,
  });
}

// 选择多帧病灶
async function selectItem(
  index: number,
  subIndex: number,
  thirdIndex: number,
  key?: string
) {
  const thirdItem: VideoType.NidusThirdItem =
    nidusList.value[index].child[subIndex].child[thirdIndex];
  thirdItem.isActive = !thirdItem.isActive;
  if (thirdItem.isActive) {
    //设置小征象
    setSmallSign(thirdItem);
    //跳到病灶所在帧并渲染
    changeVideoIndex(thirdItem);
    setNidusActive(index, subIndex, thirdIndex, true);
    setFrameActive(index, subIndex, true);
    setNidusListColor(index, subIndex, thirdIndex, true);
  } else {
    setNidusActive(index, subIndex, subIndex, false);
    setNidusListColor(index, subIndex, thirdIndex, false);
    setBigSign();
  }

  if (key === "clickNidus") {
    setToolDisabled();
  }
  setTimeout(() => {
    formRef.seriesMinSetForm && formRef.seriesMinSetForm.validate();
  });
  if (isView) return;
  setTimeout(() => {
    bus.emit("NidusList.clickNidus", thirdItem);
  }, 200);
}

//设置当前的视频列表数据
async function setVideoListActive(index: number) {
  await setSeriesResultInfo(videoList.value[index].sarId);
  videoList.value.forEach((item: VideoItem, _index: number) => {
    item.isActive = index === _index;
  });
}

//大征象验证错误
async function validateBigSignError(index: number, callback: Function) {
  if (currentVideoListIndex.value !== index) {
    //切换序列
    await setVideoListActive(index);
  }
  nextTick(() => {
    //清除当前序列的所有病灶标注颜色
    setNidusListColor(index, 0, 0, false);
    //取消当前所有病灶的选中状态
    // setNidusListActive(index, 0, 0, false, false);
    setFrameActive(index, 0, false);
    setNidusActive(index, 0, 0, false);
    //设置大征象数据
    setBigSign();
    callback();
  });
}

//小征象验证错误(帧段)
async function validateSmallSignError(
  index: number,
  subIndex: number,
  thirdIndex: number,
  callback: Function
) {
  const thirdItem = nidusList.value[index].child[subIndex].child[thirdIndex];
  if (currentVideoListIndex.value !== index) {
    //切换序列
    await setVideoListActive(index);
  }
  nextTick(() => {
    // 自动切换tab
    nidusListRef.value.tabClick("multi");
    //选中病灶
    // setNidusListActive(index, subIndex, thirdIndex);
    setFrameActive(index, subIndex, true);
    setNidusActive(index, subIndex, thirdIndex, true);
    //设置病灶的小征象数据
    setSmallSign(thirdItem);
    //跳到病灶所在帧并渲染
    changeVideoIndex(thirdItem);
    //设置颜色
    setNidusListColor(index, subIndex, thirdIndex, true);
    setMenuOpenIndex();
    callback && callback();
  });
}

// 聚焦某序列的单帧小征象
async function validateSingleSmallSign(singleNidusId: number, callback: Function) {
  const thirdItem = videoStore.getSingleListItemById(singleNidusId);
  const seriesInfo = videoStore.getSingleSeriesItemById(singleNidusId);
  const index = videoStore.getSingleSeriesIndexById(singleNidusId);
  if (currentVideoListIndex.value !== index) {
    //切换序列
    await setVideoListActive(index);
  }
  nextTick(() => {
    //自动切换tab
    nidusListRef.value.tabClick("single");
    //选中病灶
    videoStore.setSingleSelected(seriesInfo.id, singleNidusId);
    //跳到对应图像
    bus.emit("VideoLabel.changeVideoIndex", {
      changeVideoIndex: thirdItem.labelIndex - 1,
      labelData: thirdItem.data,
    });
    //征象
    setSmallSign(thirdItem);
    //设置框的颜色
    setSingleColor(thirdItem, true);
    callback && callback();
  });
}

provide("validateSingleSmallSign", validateSingleSmallSign);

//选择大征象
function selectedBigSign(index: number) {
  setBigSign();
  // setNidusListActive(index, 0, 0, false, false);
  setFrameActive(index, 0, false);
  setNidusActive(index, 0, 0, false);
  setNidusListColor(index, 0, 0, false);
}

//设置大征象
function setBigSign() {
  filmReadRight.seriesSettings.form = {};
  filmReadRight.currentSubmenuItem = "";
  filmReadRight.seriesSettings.formId = currentSeriesUid.value;
  filmReadRight.seriesSettings.formOptions = [];
  let form = {};
  projectInfo.value.annotationItemList.forEach((item: any) => {
    form = {
      ...form,
      ...getBigSignForm(item.componentType, item.componentId),
    };
    getComponentData(item, 1);
  });
  filmReadRight.seriesSettings.form = form;
}

provide("setBigSign", setBigSign);

// 获取大征象的的值
function getBigSignForm(componentType: string, componentId: number) {
  const item = (currnetSeriesResultInfo.value.annotationItemResultList || []).find(
    (item: any) => item.formComponentId === componentId
  );
  let result = {
    [componentId]: getSignResultView(componentType, item),
  };
  return result;
}

//设置帧段状态
function setFrameActive(index: number, subIndex: number, subActive: boolean) {
  nidusList.value[index].child.forEach((_subItem: VideoType.NidusSubItem) => {
    _subItem.isActive = false;
  });
  if (subActive) {
    nidusList.value[index].child[subIndex].isActive = subActive;
    videoStore.activeFrame = nidusList.value[index].child[subIndex];
  } else {
    videoStore.activeFrame = null;
  }
}

provide("setFrameActive", setFrameActive);

//设置病灶状态(帧段)
function setNidusActive(
  index: number,
  subIndex: number,
  thirdIndex: number,
  thirdActive: boolean
) {
  nidusList.value[index].child.forEach((subItem: VideoType.NidusSubItem) => {
    subItem.child.forEach((thirdItem: VideoType.NidusThirdItem) => {
      thirdItem.isActive = false;
    });
  });
  if (thirdActive) {
    //todo 与单帧的互斥
    // videoStore.unSelectedAllSingle();
    //
    const len = nidusList.value[index].child[subIndex].child.length;
    if (thirdIndex < len) {
      nidusList.value[index].child[subIndex].child[thirdIndex].isActive = thirdActive;
    }
  }
}

provide("setNidusActive", setNidusActive);

const collapsed = ref(false);

function setMenuOpenIndex() {
  if (!currentNidus.value) return;
  currentNidus.value.child.forEach(
    (subItem: VideoType.NidusSubItem, subIndex: number) => {
      let isOpen = subItem.isOpen;
      subItem.child.forEach((thirdItem: VideoType.NidusThirdItem, thirdIndex: number) => {
        if (thirdItem.isActive) {
          isOpen = true;
        }
      });
      subItem.isOpen = isOpen;
    }
  );
}

const formRef: any = reactive({
  seriesSetClass: "seriesForm",
  seriesMinSetClass: "seriesMinSetForm",
});

const visible = ref(false);

const tip1 = "请确认是否有标注帧段";
const tip2 = "请确认起始、结束、关键帧是否有标注框";
const tip3 = "请确认起始、结束、关键帧是否存在多个标注框";
//追踪按钮
const handleTrace = () => {
  const { child, sarId } = currentNidus.value;
  if (child.length === 0) {
    Message.warning(tip1);
    return;
  }
  let validate = "";
  let invalidateItem = null;
  let subIndex = -1;
  for (let [index, item] of child.entries()) {
    const { startIndex, endIndex, child } = item;
    //有且仅有三个非算法框-toolname：RectangleRoi分布在不同index
    const rectArr = child.filter(
      ({ toolName, alg }: { toolName: string; alg: boolean }) =>
        toolName === "RectangleRoi" && !alg
    );
    rectArr.sort((a: any, b: any) => a.labelIndex - b.labelIndex);
    //多了
    if (rectArr.length > 3) {
      validate = "tip3";
      invalidateItem = item;
      subIndex = index;
      break;
    }
    //不在特定位置
    if (
      !rectArr[0] ||
      !rectArr[1] ||
      !rectArr[2] ||
      startIndex !== rectArr[0].labelIndex ||
      endIndex !== rectArr[2].labelIndex ||
      startIndex >= rectArr[1].labelIndex ||
      endIndex <= rectArr[1].labelIndex
    ) {
      validate = "tip2";
      invalidateItem = item;
      subIndex = index;
      break;
    }
  }
  if (validate === "tip2") {
    Message.warning(tip2);
    //定位到对应帧段todo
    utilHooks.lesionEvent.frameActive(
      nidusList.value[currentVideoListIndex.value].child[subIndex].id as number
    ); //高亮帧段
    return;
  }
  if (validate === "tip3") {
    Message.warning(tip3);
    //定位到对应帧段
    utilHooks.lesionEvent.frameActive(
      nidusList.value[currentVideoListIndex.value].child[subIndex].id as number
    ); //高亮帧段
    return;
  }
  //如何判断是否修改过？后端判断，考虑刷新等情况
  //通过验证，开始追踪
  setLoading(true);
  VideoApi.algorithmTrace({ arId: sarId })
    .then((res) => {
      if (res.code === 200) {
        //成功后刷新列表
        Message.success("追踪成功");
        // filmReadStore.getResultData()//刷新列表
        // 刷新video数据
        bus.emit("NidusList.refresh");
      } else {
        // Message.success("追踪失败")
      }
      leftHooks.resetHookData();
      filmReadStore.getResultData(); //刷新列表

      bus.emit("NidusList.refresh");
      setLoading(false);
    })
    .finally(() => {
      setLoading(false);
    });
};
const offBusEvent = () => {
  // Bus.all.clear()
  // bus.all.clear()
  Bus.off("lesionClick", nidusListClick);
  Bus.off("toolBarClick", toolbarClick);
  //
  bus.off("Video.setLoading");
  bus.off("Cornerstone.measurementModified");
  bus.off("Cornerstone.measurementAdded");
  bus.off("Cornerstone.measurementCompleted");
  bus.off("Cornerstone.remove");
  bus.off("Video.handleClickTimer");
  bus.off("Video.changeVideoIndex");
  bus.off("NidusList.removeNidus");
  bus.off("NidusList.nidusToggleShowOrHide");
  bus.off("Video.slideChange");
  bus.off("sign.inputEvent");
  bus.off("Video.NidusIndexChange");
  bus.off("Tools.change");
  bus.off("sign.bigChang");
  bus.off("sign.smallChang");
  bus.off("NidusList.selectedBigSign");
  bus.off("NidusList.changeIsOpen");
  bus.off("NidusList.refresh");
  bus.off("NidusList.changeSubItemActive");
  bus.off("NidusList.toggleNidusItemHide");
  bus.off("Header.changeGroupIndex");
  bus.off("Cornerstone.singleClick");
};
const removeEvent = () => {
  document.removeEventListener("keydown", keydown);
  document.removeEventListener("keyup", keyup);
};
onBeforeUnmount(() => {
  offBusEvent();
  removeEvent();
});
</script>

<template>
  <a-spin tip="请等待，图像加载中..." class="spin-loading">
    <!-- 视频显示区域 -->
    <div class="video-container">
      <div class="video-viewer">
        <Video
          v-for="(item, index) in videoList"
          :key="`${index}-${item.seriesUid}`"
          :seriesUid="item.seriesUid"
          :seriesId="String(item.sarId)"
          :imageList="item.images"
          :currentSeriesUid="currentSeriesUid"
          :currentNidus="nidusList[index]"
          :videoItem="item"
          :seriesNumber="index"
        ></Video>
      </div>
      <VideoList :videoList="videoList" :changeVideoList="changeVideoList"> </VideoList>
    </div>
  </a-spin>
</template>

<style lang="less" scoped>
.spin-loading {
  display: block;
  width: 100%;
  height: 100%;
  :deep(.arco-spin-mask) {
    background: rgba(0, 0, 0, 0);

    .arco-spin-icon {
      color: #448e97;
    }
  }

  .video-container {
    width: 100%;
    height: 100%;
    background-color: #18252f;
    //position: relative;
    //padding-bottom: 154px;
    .video-viewer {
      width: 100%;
      height: calc(100% - 51px);
      background-color: #000000;
    }
  }
}
</style>
